<?php

namespace app\api\model;

use app\api\controller\Wxpay;
use Exception;
use think\Cache;
use think\Db;
use traits\model\SoftDelete;

class HomeOrderModel extends BaseModel
{
    use SoftDelete;

    protected $pk = 'id';
    protected $table = 'hs_home_order';
    protected static $tableName = 'home_order';

    // 自动写入时间戳字段
    protected $autoWriteTimestamp = 'int';
    // 定义时间戳字段名
    protected $createTime = 'createtime';
    protected $updateTime = 'updatetime';
    protected $deleteTime = 'deletetime';

    //状态常量
    const STATUS_PENDING_ORDER = 1;//待接单
    const STATUS_ORDER_RECEIVED = 2;//已接单
    const STATUS_COMPLETED = 3;//已完成
    const STATUS_CANCEL = 4;//已取消
    const STATUS_PAY = 5;//已支付

    public static function status()
    {
        return [
            self::STATUS_PENDING_ORDER => '待接单',
            self::STATUS_ORDER_RECEIVED => '已接单',
            self::STATUS_COMPLETED => '已完成',
            self::STATUS_CANCEL => '已取消',
            self::STATUS_PAY => '已支付',
        ];
    }

    public function goods()
    {
        return $this->belongsTo(GoodsModel::class, 'goods_id', 'id');
    }

    public static function check($id, $status, $user_id = 0)
    {
        $statusInfo = self::status();
        $model = self::where('id', $id)->find();
        if (!$model) {
            return array('code' => -1, 'msg' => '订单不存在');
        }
        if ($user_id && $model['user_id'] != $user_id) {
            return array('code' => -1, 'msg' => '订单不存在');
        }
        if ($model->status != $status) {
            return array('code' => -1, 'msg' => "不是{$statusInfo[$status]}订单,操作失败");
        }
        return array('code' => 1, 'data' => $model);
    }

    public static function cancelCheck($no)
    {
        $model = self::where('no', $no)->find();
        if (!$model) {
            return array('code' => -1, 'msg' => '订单不存在');
        }
        if ($model->status == self::STATUS_COMPLETED) {
            return array('code' => -1, 'msg' => "订单已完成，无法取消");
        }
        if ($model->status == self::STATUS_CANCEL) {
            return array('code' => -1, 'msg' => "订单已是取消状态，无需再次取消");
        }
        return array('code' => 1, 'data' => $model);
    }

    public static function createOrder($data = [])
    {
        try {
            $order_info = [
                'no' => self::getNewOrderId(2),
                'user_id' => $data['user_id'],
                'category_id' => $data['category_id'],
                'goods_id' => $data['goods_id'],
                'reserve_time' => strtotime($data['reserve_time']),
                'province' => $data['province'],
                'city' => $data['city'],
                'district' => $data['district'],
                'address' => $data['address'],
                'real_name' => $data['real_name'],
                'mobile' => $data['mobile'],
                'remark' => isset($data['remark']) ? $data['remark'] : '',
                'longitude' => isset($data['longitude']) ? $data['longitude'] : '',
                'latitude' => isset($data['latitude']) ? $data['latitude'] : '',
                'actual_price' => $data['price'],
            ];
            $order = self::create($order_info);
            if (!$order) {
                throw new Exception('订单生成失败!');
            }
            return $order;
        } catch (Exception $e) {
            return self::setErrorInfo($e->getMessage());
        }
    }

    //微信小程序支付
    public static function pay($order)
    {
        $wx = new Wxpay();
        return $wx->getPayUrl($order);
    }

    /**
     * 生成订单唯一id
     * @return string
     */
    public static function getNewOrderId($type)
    {
        list($msec, $sec) = explode(' ', microtime());
        $msectime = (float)sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000);
        $no = $type . $msectime . mt_rand(10000, 99999);
        if (self::where('no', $no)->find()) {
            $no = $type . $msectime . mt_rand(10000, 99999);
        }
        return $no;
    }


    //接单
    public static function take($uid, $order)
    {
        try {
            $key = md5($order->no);
            if (Cache::has($key)) {
                throw new Exception('订单已被接走');
            }
            Cache::set($key, 1, 120);
            Db::startTrans();
            $order = self::where('id', $order->id)->lock(true)->find();
            $order->role_id = $uid;
            $order->take_time = time();
            $order->status = self::STATUS_ORDER_RECEIVED;
            if (!$order->save()) {
                throw new Exception('操作失败');
            }
            Cache::rm($key);
            Db::commit();
            return true;
        } catch (Exception $e) {
            Db::rollback();
            Cache::rm($key);
            return self::setErrorInfo($e->getMessage());
        }
    }

    //确认完成订单
    public static function complete($uid, $order)
    {
        try {
            if ($order->role_id != $uid) {
                throw new Exception('非法操作');
            }
            Db::startTrans();
            //更新用户的订单状态
            $order->complete_time = time();
            $order->status = self::STATUS_COMPLETED;
            if (!$order->save()) {
                throw new Exception('更新订单信息失败');
            }
            Db::commit();
            return true;
        } catch (Exception $e) {
            Db::rollback();
            return self::setErrorInfo($e->getMessage());
        }
    }

    //订单列表
    public static function lst($user_id, $params)
    {
        $page = !empty($params['page']) ? $params['page'] : 1;
        $limit = !empty($params['limit']) ? $params['limit'] : 10;
        $user = UserModel::info($user_id);
        $list = self::order('createtime desc')->with('goods');
        if ($user['role'] == UserModel::ROLE_HOUSEKEEPER) {
            if (isset($params['status']) && $params['status']) {
                switch ($params['status']) {
                    case self::STATUS_PENDING_ORDER:
                        $list = $list->where('status', self::STATUS_PENDING_ORDER);
                        break;
                    case self::STATUS_ORDER_RECEIVED:
                    case self::STATUS_COMPLETED:
                        $list = $list->where('role_id', $user_id)->where('status', $params['status']);
                        break;
                    case self::STATUS_CANCEL:
                        $list = $list->where('status', $params['status'])
                            ->where(function ($query) use ($user_id) {
                                $query->where('role_id', $user_id)->whereOr('user_id', $user_id);
                            });
                        break;
                    default:
                        break;
                }
            }
        } else {
            $list = $list->where('user_id', $user_id);
        }
        if (isset($params['status']) && $params['status']) {
            $list = $list->where('status', $params['status']);
        }
        $list = $list->page((int)$page, (int)$limit);
        $list = $list->select();
        $data = [];
        $status = self::status();
        $categorys = CategoryModel::typeArr(CategoryModel::TYPE_HOME);
        foreach ($list as $key => $value) {
            $data[$key]['id'] = $value['id'];
            $data[$key]['no'] = $value['no'];
            $data[$key]['category_id'] = $value['category_id'];
            $data[$key]['category_name'] = isset($categorys[$value['category_id']]) ? $categorys[$value['category_id']] : '';
            $data[$key]['goods_id'] = $value['goods_id'];
            $data[$key]['goods_name'] = isset($value['goods']['title']) ? $value['goods']['title'] : '';
            $data[$key]['reserve_time'] = date('Y-m-d H:i:s', $value['reserve_time']);
            $data[$key]['province'] = $value['province'];
            $data[$key]['city'] = $value['city'];
            $data[$key]['district'] = $value['district'];
            $data[$key]['address'] = $value['address'];
            $data[$key]['real_name'] = $value['real_name'];
            $data[$key]['mobile'] = $value['mobile'];
            $data[$key]['actual_price'] = $value['actual_price'];
            $data[$key]['status'] = $value['status'];
            $data[$key]['status_name'] = isset($status[$value['status']]) ? $status[$value['status']] : '';
            $data[$key]['is_self'] = $value['user_id'] == $user_id ? 1 : 0;
        }
        return $data;
    }

    //取消回收订单
    public static function cancel($user, $order)
    {
        try {
            Db::startTrans();
            $refund_no = '';
            //如果订单已经支付，进行退款操作
            if ($order['payment_no']) {
                $wx = new Wxpay();
                if (!$refund_no = $wx->refund($order)) {
                    throw new Exception('退款失败');
                }
            }
            $order->status = self::STATUS_CANCEL;
            $order->cancel_id = $user['id'];
            $order->cancel_time = time();
            $order->refund_no = $refund_no;
            if (!$order->save()) {
                throw new Exception('更新订单信息失败');
            }
            Db::commit();
            return true;
        } catch (Exception $e) {
            Db::rollback();
            return self::setErrorInfo($e->getMessage());
        }


    }

}